package com.liangxy.news.ui.viewmodel;

import android.app.Application;
import android.util.Log;

import androidx.annotation.NonNull;
import androidx.lifecycle.AndroidViewModel;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;

import com.liangxy.news.api.ApiClient;
import com.liangxy.news.api.NewsApiService;
import com.liangxy.news.api.NewsDetailResponse;
import com.liangxy.news.database.AppDatabase;
import com.liangxy.news.database.NewsDao;
import com.liangxy.news.database.NewsDetailDao;
import com.liangxy.news.model.News;
import com.liangxy.news.model.NewsDetail;
import com.liangxy.news.repository.NewsRepository;
import com.liangxy.news.util.MockDataProvider;
import com.liangxy.news.util.SharedPreferencesManager;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;

/**
 * ViewModel for news detail page
 */
public class NewsDetailViewModel extends AndroidViewModel {
    
    private static final String TAG = "NewsDetailViewModel";
    
    private final NewsApiService apiService;
    private final NewsDao newsDao;
    private final NewsDetailDao newsDetailDao;
    private final ExecutorService executorService;
    private final SharedPreferencesManager preferencesManager;
    
    private final MutableLiveData<NewsDetail> newsDetail = new MutableLiveData<>();
    private final MutableLiveData<News> news = new MutableLiveData<>();
    private final MutableLiveData<Boolean> isLoading = new MutableLiveData<>(false);
    private final MutableLiveData<String> errorMessage = new MutableLiveData<>(null);
    private final MutableLiveData<String> currentNewsId = new MutableLiveData<>();
    private final MutableLiveData<String> currentUserId = new MutableLiveData<>();
    
    private final NewsRepository newsRepository;
    private boolean useMockData = false;
    
    public NewsDetailViewModel(@NonNull Application application) {
        super(application);
        AppDatabase database = AppDatabase.getInstance(application);
        newsDao = database.newsDao();
        newsDetailDao = database.newsDetailDao();
        apiService = ApiClient.getNewsApiService();
        executorService = Executors.newFixedThreadPool(2);
        newsRepository = NewsRepository.getInstance(application);
        preferencesManager = new SharedPreferencesManager(application);
        
        // 检查是否使用模拟数据
        useMockData = newsRepository.isUsingMockData();
    }
    
    /**
     * 设置是否使用模拟数据
     * @param useMock 是否使用模拟数据
     */
    public void setUseMockData(boolean useMock) {
        this.useMockData = useMock;
        newsRepository.setUseMockData(useMock);
    }
    
    /**
     * Load news detail by ID
     * @param newsId News ID
     */
    public void loadNewsDetail(String newsId) {
        if (newsId == null || newsId.isEmpty()) {
            errorMessage.setValue("无效的新闻ID");
            return;
        }
        
        currentNewsId.setValue(newsId);
        isLoading.setValue(true);
        errorMessage.setValue(null);
        
        // 先从本地数据库加载新闻数据
        executorService.execute(() -> {
            News localNews = newsDao.getNewsById(newsId);
            if (localNews != null) {
                news.postValue(localNews);
                
                // 同时更新阅读时间
                newsDao.updateNewsLastReadTime(newsId, System.currentTimeMillis());
            }
            
            // 从本地数据库加载新闻详情
            NewsDetail localDetail = newsDetailDao.getNewsDetailByNewsId(newsId);
            if (localDetail != null) {
                newsDetail.postValue(localDetail);
                isLoading.postValue(false);
            } else {
                // 如果本地没有详情，则从API获取
                loadNewsDetailFromApi(newsId);
            }
        });
    }
    
    /**
     * Load news detail from API
     * @param newsId News ID
     */
    private void loadNewsDetailFromApi(String newsId) {
        if (useMockData) {
            // 使用模拟数据
            handleMockNewsDetailResponse(MockDataProvider.getNewsDetail(newsId), newsId);
            return;
        }
        
        isLoading.postValue(true);
        Log.d(TAG, "开始从API获取新闻详情: " + newsId);
        
        apiService.getNewsDetail(ApiClient.getApiKey(), newsId).enqueue(new Callback<NewsDetailResponse>() {
            @Override
            public void onResponse(Call<NewsDetailResponse> call, Response<NewsDetailResponse> response) {
                isLoading.postValue(false);
                if (response.isSuccessful() && response.body() != null) {
                    NewsDetailResponse detailResponse = response.body();
                    if (detailResponse.getErrorCode() == 0 && detailResponse.getResult() != null) {
                        // 提取详情内容
                        String content = extractContent(detailResponse);
                        String title = extractTitle(detailResponse);
                        String date = extractDate(detailResponse);
                        String author = extractAuthor(detailResponse);
                        
                        // 确保内容不为空
                        if (content == null || content.isEmpty()) {
                            content = "<h1>" + title + "</h1><p>获取到的新闻详情内容为空，请稍后再试。</p>";
                            Log.w(TAG, "API返回的新闻详情内容为空，使用默认内容");
                        }
                        
                        // 输出日志以便调试
                        Log.d(TAG, "新闻详情API响应: newsId=" + newsId + 
                              ", title=" + title + 
                              ", contentLength=" + (content != null ? content.length() : 0));
                        
                        final String finalContent = content;
                        final String finalTitle = title;
                        final String finalDate = date;
                        final String finalAuthor = author;
                        
                        // 创建详情对象
                        NewsDetail detail = new NewsDetail(
                                newsId,
                                finalTitle,
                                finalDate,
                                finalAuthor,
                                finalContent
                        );
                        
                        // 保存到数据库并更新UI
                        saveNewsDetailToDatabase(detail, newsId);
                    } else {
                        String errorMsg = "API错误: " + detailResponse.getReason();
                        errorMessage.postValue(errorMsg);
                        Log.e(TAG, errorMsg);
                        
                        // 创建一个基本的错误详情
                        createAndSaveErrorDetail(newsId, "API返回错误: " + detailResponse.getReason());
                    }
                } else {
                    String errorMsg = "网络请求失败，状态码: " + response.code();
                    errorMessage.postValue("网络请求失败");
                    Log.e(TAG, errorMsg);
                    
                    // 创建一个基本的错误详情
                    createAndSaveErrorDetail(newsId, "网络请求失败，状态码: " + response.code());
                }
            }
            
            @Override
            public void onFailure(Call<NewsDetailResponse> call, Throwable t) {
                isLoading.postValue(false);
                String errorMsg = "网络请求失败: " + t.getMessage();
                errorMessage.postValue(errorMsg);
                Log.e(TAG, errorMsg, t);
                
                // 创建一个基本的错误详情
                createAndSaveErrorDetail(newsId, "网络连接失败: " + t.getMessage());
            }
        });
    }
    
    /**
     * 从API响应中提取内容
     */
    private String extractContent(NewsDetailResponse detailResponse) {
        String content = "";
        
        // 首先检查Result中的content字段
        if (detailResponse.getResult().getContent() != null && 
            !detailResponse.getResult().getContent().isEmpty()) {
            content = detailResponse.getResult().getContent();
            Log.d(TAG, "从Result.content提取内容，长度: " + content.length());
        }
        
        // 如果content为空，检查Detail对象
        if ((content == null || content.isEmpty()) && 
            detailResponse.getResult().getDetail() != null &&
            detailResponse.getResult().getDetail().getContent() != null && 
            !detailResponse.getResult().getDetail().getContent().isEmpty()) {
            
            content = detailResponse.getResult().getDetail().getContent();
            Log.d(TAG, "从Result.detail.content提取内容，长度: " + content.length());
        }
        
        return content;
    }
    
    /**
     * 从API响应中提取标题
     */
    private String extractTitle(NewsDetailResponse detailResponse) {
        if (detailResponse.getResult().getDetail() != null && 
            detailResponse.getResult().getDetail().getTitle() != null) {
            return detailResponse.getResult().getDetail().getTitle();
        }
        return "未知标题";
    }
    
    /**
     * 从API响应中提取日期
     */
    private String extractDate(NewsDetailResponse detailResponse) {
        if (detailResponse.getResult().getDetail() != null && 
            detailResponse.getResult().getDetail().getDate() != null) {
            return detailResponse.getResult().getDetail().getDate();
        }
        return "未知日期";
    }
    
    /**
     * 从API响应中提取作者
     */
    private String extractAuthor(NewsDetailResponse detailResponse) {
        if (detailResponse.getResult().getDetail() != null && 
            detailResponse.getResult().getDetail().getAuthor() != null) {
            return detailResponse.getResult().getDetail().getAuthor();
        }
        return "未知来源";
    }
    
    /**
     * 创建并保存错误详情
     */
    private void createAndSaveErrorDetail(String newsId, String errorMessage) {
        Log.d(TAG, "创建错误详情记录: " + newsId + ", " + errorMessage);
        
        // 使用模拟数据
        if (useMockData) {
            handleMockNewsDetailResponse(MockDataProvider.getNewsDetail(newsId), newsId);
            return;
        }
        
        // 从数据库获取新闻基本信息
        executorService.execute(() -> {
            News newsItem = newsDao.getNewsById(newsId);
            String title = (newsItem != null && newsItem.getTitle() != null) ? 
                    newsItem.getTitle() : "未能获取详情";
            String date = (newsItem != null && newsItem.getDate() != null) ?
                    newsItem.getDate() : "未知日期";
            String author = (newsItem != null && newsItem.getAuthorName() != null) ?
                    newsItem.getAuthorName() : "未知来源";
            
            // 创建错误内容
            String errorContent = "<h1>" + title + "</h1>" +
                    "<p style='color:red;'>" + errorMessage + "</p>" +
                    "<p>请检查网络连接并稍后重试，或者联系客服寻求帮助。</p>";
            
            // 创建详情对象
            NewsDetail detail = new NewsDetail(
                    newsId,
                    title,
                    date,
                    author,
                    errorContent
            );
            
            // 保存到数据库
            saveNewsDetailToDatabase(detail, newsId);
        });
    }
    
    /**
     * 保存新闻详情到数据库
     */
    private void saveNewsDetailToDatabase(NewsDetail detail, String newsId) {
        executorService.execute(() -> {
            try {
                synchronized (NewsDetailViewModel.class) {
                    Log.d(TAG, "开始保存新闻详情到数据库: " + newsId);
                    
                    // 1. 保存详情到数据库
                    newsDetailDao.insert(detail);
                    
                    // 2. 更新新闻基本信息表中的内容
                    News newsItem = newsDao.getNewsById(newsId);
                    if (newsItem != null) {
                        Log.d(TAG, "更新现有新闻: " + newsId);
                        newsItem.setContent(detail.getContent());
                        newsItem.setIs_content(true);
                        newsItem.setTitle(detail.getTitle());
                        newsItem.setDate(detail.getDate());
                        newsItem.setAuthorName(detail.getAuthor());
                        newsDao.update(newsItem);
                    } else {
                        // 如果新闻不存在，创建一个基本新闻对象
                        Log.d(TAG, "创建新的新闻记录: " + newsId);
                        News newNews = new News();
                        newNews.setUniquekey(newsId);
                        newNews.setTitle(detail.getTitle());
                        newNews.setDate(detail.getDate());
                        newNews.setAuthorName(detail.getAuthor());
                        newNews.setContent(detail.getContent());
                        newNews.setIs_content(true);
                        newsDao.insert(newNews);
                    }
                    
                    // 3. 确保数据写入磁盘
                    AppDatabase.getInstance(null).getOpenHelper().getWritableDatabase().execSQL("PRAGMA wal_checkpoint(PASSIVE)");
                    
                    // 4. 在数据库操作完成后，更新UI
                    newsDetail.postValue(detail);
                    
                    Log.d(TAG, "新闻详情已保存到数据库，ID: " + newsId);
                }
            } catch (Exception e) {
                Log.e(TAG, "保存新闻详情到数据库时出错: " + e.getMessage(), e);
                // 即使保存失败，也尝试更新UI
                newsDetail.postValue(detail);
            }
        });
    }
    
    /**
     * 处理模拟新闻详情响应
     * @param detailResponse 模拟新闻详情响应
     * @param newsId 新闻ID
     */
    private void handleMockNewsDetailResponse(NewsDetailResponse detailResponse, String newsId) {
        isLoading.postValue(false);
        Log.d(TAG, "处理模拟新闻详情数据，ID: " + newsId);
        
        try {
            // 提取详情内容
            String content = "";
            String title = "模拟新闻";
            String date = "2023-01-01";
            String author = "模拟数据";
            
            if (detailResponse != null && detailResponse.getResult() != null) {
                // 首先检查Result中的content字段
                if (detailResponse.getResult().getContent() != null && 
                    !detailResponse.getResult().getContent().isEmpty()) {
                    content = detailResponse.getResult().getContent();
                    Log.d(TAG, "使用模拟数据的Result.content字段，长度: " + content.length());
                }
                
                if (detailResponse.getResult().getDetail() != null) {
                    // 如果content仍然为空，尝试从detail中获取
                    if (content == null || content.isEmpty()) {
                        if (detailResponse.getResult().getDetail().getContent() != null &&
                            !detailResponse.getResult().getDetail().getContent().isEmpty()) {
                            content = detailResponse.getResult().getDetail().getContent();
                            Log.d(TAG, "使用模拟数据的Result.detail.content字段，长度: " + content.length());
                        }
                    }
                
                    if (detailResponse.getResult().getDetail().getTitle() != null) {
                        title = detailResponse.getResult().getDetail().getTitle();
                    }
                
                    if (detailResponse.getResult().getDetail().getDate() != null) {
                        date = detailResponse.getResult().getDetail().getDate();
                    }
                
                    if (detailResponse.getResult().getDetail().getAuthor() != null) {
                        author = detailResponse.getResult().getDetail().getAuthor();
                    }
                }
            }
            
            // 确保内容不为空
            if (content == null || content.isEmpty()) {
                content = "<h1>" + title + "</h1>" +
                          "<p>这是一条模拟新闻的详细内容。</p>" +
                          "<p>由于无法从API获取实际内容，我们为您准备了这条模拟新闻。</p>" +
                          "<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>" +
                          "<img src=\"https://via.placeholder.com/800x400?text=News+Image\" alt=\"新闻图片\">" +
                          "<p>Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.</p>";
                Log.d(TAG, "模拟数据内容为空，使用默认测试内容");
            }
            
            // 输出模拟数据信息
            Log.d(TAG, "模拟新闻详情: newsId=" + newsId + ", title=" + title + ", contentLength=" + content.length());
            
            // 创建详情对象
            NewsDetail detail = new NewsDetail(
                    newsId,
                    title,
                    date,
                    author,
                    content
            );
            
            // 保存到数据库并更新UI
            saveNewsDetailToDatabase(detail, newsId);
            
        } catch (Exception e) {
            Log.e(TAG, "处理模拟数据时出错: " + e.getMessage(), e);
            
            // 创建一个基本的错误详情
            createAndSaveErrorDetail(newsId, "处理模拟数据时出错: " + e.getMessage());
        }
    }
    
    /**
     * Set current user ID
     * @param userId User ID
     */
    public void setUserId(String userId) {
        if ((userId == null && currentUserId.getValue() != null) || 
            (userId != null && !userId.equals(currentUserId.getValue()))) {
            currentUserId.setValue(userId);
        }
    }
    
    public LiveData<NewsDetail> getNewsDetail() {
        return newsDetail;
    }
    
    public LiveData<News> getNews() {
        return news;
    }
    
    public LiveData<Boolean> getIsLoading() {
        return isLoading;
    }
    
    public LiveData<String> getErrorMessage() {
        return errorMessage;
    }
} 
